package com.symaster.common.swing.element.collapse;

import com.symaster.common.swing.element.collapse.item.Row;
import com.symaster.common.swing.style.Style;
import com.symaster.common.swing.util.SwingUtil;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 折叠面板
 *
 * @author yinmiao
 * @version 2022-07-18 11:33
 */
public class CollapsePanel<T extends JComponent> extends JComponent {

    private final int verticalGap;
    private final Map<JComponent, SpreadListener<T>> dataMap;
    private final List<Color> rowColors;
    private final JPanel list;
    private final JScrollPane jScrollPane;

    public CollapsePanel(int verticalGap) {
        this.verticalGap = verticalGap;
        this.dataMap = new HashMap<>();
        this.rowColors = new ArrayList<>();
        this.list = new JPanel();
        this.list.setLayout(new FlowLayout(FlowLayout.CENTER, 0, verticalGap));
        this.jScrollPane = new JScrollPane();
        this.jScrollPane.setViewportView(this.list);
        this.jScrollPane.getVerticalScrollBar().setUnitIncrement(20);
        Style.setBorder(Style.BORDER_EMPTY, jScrollPane);
        this.setLayout(new BorderLayout());
        this.add(this.jScrollPane, BorderLayout.CENTER);
        this.initRowColor();
    }

    private void initRowColor() {
        rowColors.clear();
        Color background = getBackground();
        if (background != null) {
            rowColors.add(new Color(background.getRed() - 10, background.getGreen(), background.getBlue()));
        } else {
            rowColors.add(new Color(245, 245, 245));
            rowColors.add(new Color(238, 238, 238));
        }
    }

    public void put(T component, SpreadListener<T> listener) {
        put(component, false, listener);
    }

    public void put(T component, boolean defaultShow, SpreadListener<T> listener) {
        Row<T> tRowComponent = new Row<>();
        tRowComponent.setData(component);
        Dimension itemDimension = getItemDimension();
        tRowComponent.setPreferredSize(itemDimension);
        tRowComponent.setSize(itemDimension);
        tRowComponent.setBackground(rowColors.get(getComponents().length % rowColors.size()));
        tRowComponent.setRowSpreadListener(new Row.RowSpreadListener<T>() {
            @Override
            public JComponent handler(Row<T> row) {
                return rowSpreadListener(row);
            }

            @Override
            public void over() {
                SwingUtilities.invokeLater(CollapsePanel.this::updateHeight);
            }
        });
        dataMap.put(component, listener);
        list.add(tRowComponent);
        updateHeight();
    }

    private JComponent rowSpreadListener(Row<T> row) {
        SpreadListener<T> tSpreadListener = dataMap.get(row.getData());
        if (tSpreadListener == null) {
            return null;
        }
        return tSpreadListener.handler(row.getData());
    }

    public Dimension getItemDimension() {
        return new Dimension(getWidth() - 25, 45);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        updateHeight();
    }

    private void updateHeight() {
        int h = 0;
        Dimension itemDimension = getItemDimension();
        for (Component component : list.getComponents()) {
            Dimension size = component.getPreferredSize();
            component.setPreferredSize(new Dimension(itemDimension.width, size.height));
            h += size.height + verticalGap;
        }
        Dimension dimension = new Dimension(itemDimension.width, h);
        list.setPreferredSize(dimension);
        jScrollPane.updateUI();
    }

    @Override
    public void removeAll() {
        dataMap.clear();
        list.removeAll();
        updateHeight();
    }

    public static void main(String[] args) {

        CollapsePanel<JLabel> collapsePanel = new CollapsePanel<>(0);

        JFrame jFrame = new JFrame();
        jFrame.setContentPane(collapsePanel);
        jFrame.setPreferredSize(new Dimension(900, 600));
        jFrame.pack();
        SwingUtil.toCenter(jFrame);

        collapsePanel.put(new JLabel("测试1"), CollapsePanel::textPane);
        collapsePanel.put(new JLabel("测试2"), CollapsePanel::textPane);
        collapsePanel.put(new JLabel("测试3"), CollapsePanel::textPane);
        collapsePanel.put(new JLabel("测试4"), CollapsePanel::textPane);

        jFrame.setVisible(true);
    }

    private static JComponent textPane(JLabel jLabel) {
        JLabel jLabel1 = new JLabel(jLabel.getText() + "====");
        jLabel1.setPreferredSize(new Dimension(500, 100));
        return jLabel1;
    }

    public interface SpreadListener<T> {
        JComponent handler(T rowData);
    }
}
